#include "hal_device.h"
#include "hal_sensor.h"
#include "stm32f4xx.h"
#include "stm32f4xx_ll_tim.h"
#include "stm32f4xx_ll_bus.h"
#include "stm32f4xx_ll_gpio.h"


static int stm32f4xx_pwm_gpio_init(struct hal_dev_s *dev)
{
	LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

	LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOE);

	GPIO_InitStruct.Pin        = LL_GPIO_PIN_14|LL_GPIO_PIN_13|LL_GPIO_PIN_11|LL_GPIO_PIN_9;
	GPIO_InitStruct.Mode       = LL_GPIO_MODE_OUTPUT;
	GPIO_InitStruct.Speed      = LL_GPIO_SPEED_FREQ_HIGH;
	GPIO_InitStruct.Pull       = LL_GPIO_PULL_NO;
	GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
	LL_GPIO_Init(GPIOE, &GPIO_InitStruct);
	
	return 0;
}


static int stm32f4xx_pwm_init(struct hal_dev_s *dev)
{
	stm32f4xx_pwm_gpio_init(dev);
	return 0;
}

static int stm32f4xx_pwm_open(struct hal_dev_s *dev,uint16_t flag)
{
	LL_GPIO_ResetOutputPin(GPIOE,LL_GPIO_PIN_9);
	LL_GPIO_ResetOutputPin(GPIOE,LL_GPIO_PIN_11);
	LL_GPIO_ResetOutputPin(GPIOE,LL_GPIO_PIN_13);
	LL_GPIO_ResetOutputPin(GPIOE,LL_GPIO_PIN_14);
	
	return 0;
}

static int stm32f4xx_pwm_write(struct hal_dev_s *dev, const void *buffer, int buflen,int pos)
{
	struct motor_data_s *motor = (struct motor_data_s *)buffer;
	
	if(buflen != sizeof(struct motor_data_s)){
		return -1;
	}
	
	if(motor->channel[0] > 0.5f){
		LL_GPIO_ResetOutputPin(GPIOE,LL_GPIO_PIN_9);
		LL_GPIO_ResetOutputPin(GPIOE,LL_GPIO_PIN_11);
		LL_GPIO_ResetOutputPin(GPIOE,LL_GPIO_PIN_13);
		LL_GPIO_ResetOutputPin(GPIOE,LL_GPIO_PIN_14);
	}else {
		LL_GPIO_SetOutputPin(GPIOE,LL_GPIO_PIN_9);
		LL_GPIO_SetOutputPin(GPIOE,LL_GPIO_PIN_11);
		LL_GPIO_SetOutputPin(GPIOE,LL_GPIO_PIN_13);
		LL_GPIO_SetOutputPin(GPIOE,LL_GPIO_PIN_14);
	}
	
	return buflen;
}


struct hal_dev_s stm32f4xx_gpio_pwm_dev;

int stm32f4xx_gpio_pwm_register(void)
{
	stm32f4xx_gpio_pwm_dev.init  = stm32f4xx_pwm_init;
	stm32f4xx_gpio_pwm_dev.open  = stm32f4xx_pwm_open;
	stm32f4xx_gpio_pwm_dev.write = stm32f4xx_pwm_write;
	
	hal_dev_register(&stm32f4xx_gpio_pwm_dev,"pwm",HAL_O_WRONLY);
	return 0;
}
